<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>redux-form(v6)翻译 | Ted Yuen的技术博客</title>
    <meta name="description" content="React中没有类似Angular那样的双向数据绑定，在做一些表单复杂的后台类页面时，监听、赋值、传递、校验时编码相对复杂，满屏的样板代码伤痛欲绝，故引入可以解决这些问题的 redux-form (v6) 模块。本文大致翻译了官方文档一些比较重要的地方，结合官方Demo加入了一些特性，有些官方跑不起来的地方也进行了优化。

项目地址: [https://github.com/tedyu ...">
    <meta name="generator" content="VuePress 1.4.0">
    
    
    <link rel="preload" href="/assets/css/0.styles.b6e5dee4.css" as="style"><link rel="preload" href="/assets/js/app.a5c0d474.js" as="script"><link rel="preload" href="/assets/js/15.57df9f8e.js" as="script"><link rel="preload" href="/assets/js/17.06d3e00b.js" as="script"><link rel="prefetch" href="/assets/js/10.262e0963.js"><link rel="prefetch" href="/assets/js/11.03a057c9.js"><link rel="prefetch" href="/assets/js/12.63659604.js"><link rel="prefetch" href="/assets/js/13.0549c43a.js"><link rel="prefetch" href="/assets/js/14.e794c180.js"><link rel="prefetch" href="/assets/js/16.a0d9468b.js"><link rel="prefetch" href="/assets/js/18.0d80b21a.js"><link rel="prefetch" href="/assets/js/19.1e9da99b.js"><link rel="prefetch" href="/assets/js/20.08d3d7c6.js"><link rel="prefetch" href="/assets/js/21.b1aee962.js"><link rel="prefetch" href="/assets/js/22.4f410a60.js"><link rel="prefetch" href="/assets/js/23.6d06a125.js"><link rel="prefetch" href="/assets/js/24.f7a70963.js"><link rel="prefetch" href="/assets/js/25.5ee1e916.js"><link rel="prefetch" href="/assets/js/26.7bdc3bcf.js"><link rel="prefetch" href="/assets/js/27.15c6e05a.js"><link rel="prefetch" href="/assets/js/28.ae822034.js"><link rel="prefetch" href="/assets/js/29.170e7a57.js"><link rel="prefetch" href="/assets/js/3.d6f86d84.js"><link rel="prefetch" href="/assets/js/30.191f3008.js"><link rel="prefetch" href="/assets/js/31.5175acc4.js"><link rel="prefetch" href="/assets/js/32.73255ebc.js"><link rel="prefetch" href="/assets/js/33.203b8fc2.js"><link rel="prefetch" href="/assets/js/4.a2169bd0.js"><link rel="prefetch" href="/assets/js/5.894072dc.js"><link rel="prefetch" href="/assets/js/6.f66a1900.js"><link rel="prefetch" href="/assets/js/7.cbb4d687.js"><link rel="prefetch" href="/assets/js/8.d2217048.js"><link rel="prefetch" href="/assets/js/9.0d6d3c54.js"><link rel="prefetch" href="/assets/js/vuejs-paginate.643397bf.js">
    <link rel="stylesheet" href="/assets/css/0.styles.b6e5dee4.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container" data-v-c305a0ca><header class="navbar" data-v-c305a0ca><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">Ted Yuen的技术博客</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">
  博文
</a></div><div class="nav-item"><a href="/tag/" class="nav-link">
  标签云
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="专栏" class="dropdown-title"><span class="title">专栏</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/tag/Vocabulary/" class="nav-link">
  程序员英语词汇
</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/tedyuen" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask" data-v-c305a0ca></div> <aside class="sidebar" data-v-c305a0ca><nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">
  博文
</a></div><div class="nav-item"><a href="/tag/" class="nav-link">
  标签云
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="专栏" class="dropdown-title"><span class="title">专栏</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/tag/Vocabulary/" class="nav-link">
  程序员英语词汇
</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/tedyuen" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>redux-form(v6)翻译</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/2017/07/04/react-redux-form-v6-example/#起步" class="sidebar-link">起步</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/2017/07/04/react-redux-form-v6-example/#表单value的生命周期" class="sidebar-link">表单value的生命周期</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/2017/07/04/react-redux-form-v6-example/#api" class="sidebar-link">API</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#reduxform-config-object" class="sidebar-link">reduxForm(config:Object)</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#props" class="sidebar-link">props</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#field" class="sidebar-link">Field</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#fields" class="sidebar-link">Fields</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#fieldarray" class="sidebar-link">FieldArray</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#form" class="sidebar-link">Form</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#formsection" class="sidebar-link">FormSection</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#formvalues" class="sidebar-link">formValues()</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#formvalueselector" class="sidebar-link">formValueSelector()</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#reducer" class="sidebar-link">reducer</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#reducer-plugin" class="sidebar-link">reducer.plugin</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#submissionerror" class="sidebar-link">SubmissionError</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#action-creators" class="sidebar-link">Action Creators</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#selectors" class="sidebar-link">Selectors</a></li></ul></li><li><a href="/2017/07/04/react-redux-form-v6-example/#examples" class="sidebar-link">Examples</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#simple-form" class="sidebar-link">Simple Form</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#sync-validation" class="sidebar-link">Sync Validation</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#field-level-validation" class="sidebar-link">Field-Level Validation</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#submit-validation" class="sidebar-link">Submit Validation</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#async-validation" class="sidebar-link">Async Validation</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#initialize-from-state" class="sidebar-link">Initialize From State</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#selecting-form-values" class="sidebar-link">Selecting Form Values</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#field-array" class="sidebar-link">Field Array</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#remote-submit" class="sidebar-link">Remote Submit</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#field-normalizing" class="sidebar-link">Field Normalizing</a></li><li class="sidebar-sub-header"><a href="/2017/07/04/react-redux-form-v6-example/#wizard" class="sidebar-link">Wizard</a></li></ul></li></ul></section></li></ul> </aside> <div data-v-c305a0ca><main class="page"> <article class="theme-default-content"><header><h1 itemprop="name headline" class="post-title">
        redux-form(v6)翻译
      </h1> <div class="post-meta"><div itemprop="publisher author" itemtype="http://schema.org/Person" itemscope="itemscope" class="post-meta-author"><svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-navigation"><polygon points="3 11 22 2 13 21 11 13 3 11"></polygon></svg> <span itemprop="name">Ted Yuen</span> <span itemprop="address">   in Shanghai</span></div> <div class="post-meta-date"><svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg> <time pubdate itemprop="datePublished" datetime="2017-7-4">
      Tue Jul 04 2017
    </time></div> <ul itemprop="keywords" class="post-meta-tags"><li class="post-tag" data-v-6958873e><a href="/tag/React" data-v-6958873e> React </a></li><li class="post-tag" data-v-6958873e><a href="/tag/Redux" data-v-6958873e> Redux </a></li><li class="post-tag" data-v-6958873e><a href="/tag/Redux-Form" data-v-6958873e> Redux-Form </a></li></ul></div></header> <div class="content__default"><blockquote><p>React中没有类似Angular那样的双向数据绑定，在做一些表单复杂的后台类页面时，监听、赋值、传递、校验时编码相对复杂，满屏的样板代码伤痛欲绝，故引入可以解决这些问题的 <code>redux-form</code> (v6) 模块。本文大致翻译了官方文档一些比较重要的地方，结合官方Demo加入了一些特性，有些官方跑不起来的地方也进行了优化。</p></blockquote> <ul><li>项目地址: <a href="https://github.com/tedyuen/react-redux-form-v6-example" target="_blank" rel="noopener noreferrer">https://github.com/tedyuen/react-redux-form-v6-example<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://tedyuen.github.io/redux-form-demo" target="_blank" rel="noopener noreferrer">在线演示地址<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>本地演示方法: <code>npm install &amp;&amp; npm run start</code></li> <li>如对翻译有困惑，请移步<a href="http://redux-form.com/6.8.0/" target="_blank" rel="noopener noreferrer">官方文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>，对Demo的理解有异议欢迎留言或私信。转载请注明出处<a href="https://github.com/tedyuen/react-redux-form-v6-example/blob/master/README.md" target="_blank" rel="noopener noreferrer">Ted Yuen<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <h2 id="起步"><a href="#起步" class="header-anchor">#</a> 起步</h2> <h4 id="在使用-redux-form-之前，需要具备以下基础"><a href="#在使用-redux-form-之前，需要具备以下基础" class="header-anchor">#</a> 在使用 <code>redux-form</code> 之前，需要具备以下基础:</h4> <ul><li><a href="http://redux.js.org/" target="_blank" rel="noopener noreferrer">Redux<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> （<a href="http://cn.redux.js.org/" target="_blank" rel="noopener noreferrer">中文<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>）</li> <li><a href="https://facebook.github.io/react/" target="_blank" rel="noopener noreferrer">React<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 和 <a href="https://facebook.github.io/react/docs/higher-order-components.html" target="_blank" rel="noopener noreferrer">高阶组件<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <h4 id="关于-redux-form-的三个主要模块"><a href="#关于-redux-form-的三个主要模块" class="header-anchor">#</a> 关于 <code>redux-form</code> 的三个主要模块:</h4> <ul><li><strong><code>formReducer reducer</code></strong> : 表单的各种操作以 Redux action 的方式，通过此 reducer 来促使 Redux store 数据的变化。</li> <li><strong><code>reduxForm() HOC</code></strong> : 此高阶组件用以整合 Redux action 绑定的用户交互与您的组件，并返回一个新的组件供以使用。</li> <li><strong><code>&lt;Field/&gt;</code></strong> : 用此代替您原本的 <code>&lt;input/&gt;</code> 组件，可以与redux-form的逻辑相连接。</li></ul> <h4 id="数据流"><a href="#数据流" class="header-anchor">#</a> 数据流:</h4> <p>在大部分情况下您不需要关心如何创建action，一切都是自动的。下图展示了一个简易的数据流:</p> <p><img src="https://raw.githubusercontent.com/erikras/redux-form/master/docs/reduxFormDiagram.png" alt="Data flow"></p> <p>举个简单的例子，我们有一个被 <code>reduxForm()</code> 创建的表单组件，里面有一个用 <code>&lt;Field/&gt;</code> 创建的 <code>&lt;input/&gt;</code> 组件，数据流大概是这个样子的:</p> <ol><li>用户点击这个 <code>&lt;input/&gt;</code> 组件,</li> <li>&quot;Focus action&quot; 被触发,</li> <li>formReducer 更新了对应的状态,</li> <li>这个状态被传回 <code>&lt;input/&gt;</code> 组件中。</li></ol> <p>与此类似的在这个 <code>&lt;input/&gt;</code> 中输入文字、更改状态、提交表单，也是遵循以上这个流程。</p> <p><code>redux-form</code> 还能基于此流程处理许多事情，诸如:表单验证与格式化，多参数与action的创建。基于以下的向导，请自助挖掘更深层次的功能。</p> <h4 id="基本使用向导"><a href="#基本使用向导" class="header-anchor">#</a> 基本使用向导</h4> <h5 id="步骤-1-4-form-reducer"><a href="#步骤-1-4-form-reducer" class="header-anchor">#</a> 步骤 1/4: Form reducer</h5> <p>store需要知道组件如何发送action,因此我们需要在您的store中注册 <code>formReducer</code>，他可以服务于整个app中你定义的所有表单组件，因此只需要注册一次。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore<span class="token punctuation">,</span> combineReducers <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> reducer <span class="token keyword">as</span> formReducer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span>

<span class="token keyword">const</span> rootReducer <span class="token operator">=</span> <span class="token function">combineReducers</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// ...your other reducers here</span>
  <span class="token comment">// you have to pass formReducer under 'form' key,</span>
  <span class="token comment">// for custom keys look up the docs for 'getFormState'</span>
  form<span class="token operator">:</span> formReducer
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span>rootReducer<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>注: 在reducer中合并的formReducer的key必须命名为&quot;form&quot;。如果您因某些原因需要自定义key，请移步 <a href="#getformstate-config">getFormState config</a>查看详情。</p> <h5 id="步骤-2-4-form-component"><a href="#步骤-2-4-form-component" class="header-anchor">#</a> 步骤 2/4: Form component</h5> <p>为了使您的表单组件可以与store进行交互，我们需要使用高价函数 <code>reduxForm()</code> 来包裹您的组件。他可以在您执行提交表单等操作的时候，以props的方式提供表单内的state。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Field<span class="token punctuation">,</span> reduxForm <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span>

<span class="token keyword">let</span> <span class="token function-variable function">ContactForm</span> <span class="token operator">=</span> <span class="token parameter">props</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">{</span> handleSubmit <span class="token punctuation">}</span> <span class="token operator">=</span> props
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>form onSubmit<span class="token operator">=</span><span class="token punctuation">{</span> handleSubmit <span class="token punctuation">}</span><span class="token operator">&gt;</span>
      <span class="token punctuation">{</span> <span class="token comment">/* form body*/</span> <span class="token punctuation">}</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>form<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

ContactForm <span class="token operator">=</span> <span class="token function">reduxForm</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// a unique name for the form</span>
  form<span class="token operator">:</span> <span class="token string">'contact'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>ContactForm<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> ContactForm<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><p>现在我们已经有一个表单组件了，让我们添加一些input组件。</p> <p>注: 如果您觉得 ()() 这类的语法很迷惑，您可以把它分两步来看:</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token comment">// ...</span>

<span class="token comment">// create new, &quot;configured&quot; function</span>
createReduxForm <span class="token operator">=</span> <span class="token function">reduxForm</span><span class="token punctuation">(</span><span class="token punctuation">{</span> form<span class="token operator">:</span> <span class="token string">'contact'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// evaluate it for ContactForm component</span>
ContactForm <span class="token operator">=</span> <span class="token function">createReduxForm</span><span class="token punctuation">(</span> ContactForm <span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> ContactForm<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h5 id="步骤-3-4-form-field-components"><a href="#步骤-3-4-form-field-components" class="header-anchor">#</a> 步骤 3/4: Form <code>&lt;Field/&gt;</code> Components</h5> <p><code>&lt;Field/&gt;</code> 组件可以连接所有input类型组件的数据到store中，基本用法如下:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>inputName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>它创建了一个text类型的<code>&lt;input/&gt;</code>组件，还提供了诸如 <code>value</code> <code>onChange</code> <code>onBlur</code>等属性，用于跟踪和维护此组件的各种状态。</p> <p>注: <code>&lt;Field/&gt;</code> 组件很强大，除了基本的类型，还可以配置类或者无状态组件，欲了解更多，请移步<a href="#field-usage">Field usage</a>。</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> Field<span class="token punctuation">,</span> reduxForm <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span>

<span class="token keyword">const</span> <span class="token function-variable function">ContactForm</span> <span class="token operator">=</span> <span class="token parameter">props</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">{</span> handleSubmit <span class="token punctuation">}</span> <span class="token operator">=</span> props
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span> handleSubmit <span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">htmlFor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>firstName<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">First Name</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>firstName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">htmlFor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>lastName<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Last Name</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>lastName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">htmlFor</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>email<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Email</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>email<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>email<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>submit<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">Submit</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">)</span>
<span class="token punctuation">}</span>

ContactForm <span class="token operator">=</span> <span class="token function">reduxForm</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// a unique name for the form</span>
  form<span class="token operator">:</span> <span class="token string">'contact'</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>ContactForm<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> ContactForm<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br></div></div><p>从现在开始，表单上的操作数据已经可以填充至store，并可以执行提交表单操作了。</p> <h5 id="步骤-4-4-reacting-to-submit"><a href="#步骤-4-4-reacting-to-submit" class="header-anchor">#</a> 步骤 4/4: Reacting to submit</h5> <p>提交的数据以JSON对象的形式注入了此表单组件的 <code>onSubmit</code> 方法里了，可以打印出来看:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> ContactForm <span class="token keyword">from</span> <span class="token string">'./ContactForm'</span>

<span class="token keyword">class</span> <span class="token class-name">ContactPage</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">submit</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">values</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// print the form values to the console</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>values<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ContactForm</span></span> <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>submit<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="表单value的生命周期"><a href="#表单value的生命周期" class="header-anchor">#</a> 表单value的生命周期</h2> <p>本节对理解您的组件value通过 <code>redux-form</code> 的流向很重要</p> <h4 id="value-生命周期钩子函数"><a href="#value-生命周期钩子函数" class="header-anchor">#</a> Value 生命周期钩子函数</h4> <p><code>redux-form</code> 提供了3个 value 生命周期钩子函数，通过props传递给Field组件，并且都是可选的。</p> <h5 id="format-value-any-string"><a href="#format-value-any-string" class="header-anchor">#</a> <em><strong><code>format(value:Any) =&gt; String</code></strong></em></h5> <p>格式化从store里拿出来的数据渲染到组件里，通常会在store保留原来的数据类型，只是在组件中使用的时候进行格式化。</p> <h5 id="parse-value-string-any"><a href="#parse-value-string-any" class="header-anchor">#</a> <em><strong><code>parse(value:String) =&gt; Any</code></strong></em></h5> <p>把用户输入的string类型的数据进行格式转化，放入store供你使用，也会在store保留转化后类型的数据。</p> <h5 id="normalize-value-any-previousvalue-any-allvalues-object-previousallvalues-object-any"><a href="#normalize-value-any-previousvalue-any-allvalues-object-previousallvalues-object-any" class="header-anchor">#</a> <em><strong><code>normalize(value:Any, previousValue:Any, allValues:Object, previousAllValues:Object) =&gt; Any</code></strong></em></h5> <p>允许您对当前字段数据添加某些约束的逻辑，比如可以约束 <code>midDate</code> 的日期在 <code>maxDate</code> 之前等。如果你添加了这些逻辑，通过 <code>normalize()</code>的value将会被解析。</p> <h4 id="value-生命周期"><a href="#value-生命周期" class="header-anchor">#</a> Value 生命周期</h4> <p><img src="https://github.com/erikras/redux-form/raw/master/docs/valueLifecycle.png" alt="value lifecycle"></p> <h2 id="api"><a href="#api" class="header-anchor">#</a> API</h2> <p>限于篇幅问题，在此只列举每一种api常用的使用方法，具体请移步<a href="http://redux-form.com/6.8.0/docs/api/" target="_blank" rel="noopener noreferrer">官方API文档<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <h3 id="reduxform-config-object"><a href="#reduxform-config-object" class="header-anchor">#</a> reduxForm(config:Object)</h3> <p>通过配置一些参数创建一个可以让你配置你的表单的修饰器。诸如配置如何做表单验证、提交成功或失败的回调、获取或失去焦点的action发送、prop命名空间等，具体例子会在之后的demo中介绍。</p> <h5 id="importing"><a href="#importing" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> reduxForm <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>reduxForm<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> reduxForm <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="常用参数介绍"><a href="#常用参数介绍" class="header-anchor">#</a> 常用参数介绍</h5> <p>必要参数</p> <ul><li><code>form : String[required]</code> : 用于命名您的表单，在store生成此命名的数据节点。</li></ul> <p>可选参数</p> <ul><li><code>onChange : Function [optional]</code> : 表单触发 onChange 事件后的回调。</li> <li><code>onSubmit : Function [optional[</code> : 表单提交配置，可以配置需要提交哪些参数，还有提交时触发的 <code>dispatch</code>等。</li> <li><code>onSubmitSuccess : Function [optional]</code> &amp; <code>onSubmitFail : Function [optional]</code> : 提交表单成功和失败的回调。</li> <li><code>shouldValidate(params) : boolean [optional]</code> : 同步验证。</li> <li><code>shouldAsyncValidate(params) : boolean [optional]</code> : 异步验证。</li> <li><code>touchOnBlur : boolean [optional]</code> &amp; <code>touchOnChange : boolean [optional]</code> : 标识 <code>onBlur</code> 或 <code>onChange</code> 的触发。</li></ul> <h3 id="props"><a href="#props" class="header-anchor">#</a> props</h3> <p>列出全部当前页面由 <code>redux-form</code> 生成用于修饰此表单组件的props。</p> <p>如果你希望用严格模式来编写 PropTypes， <code>redux-form</code> 会导出此处所有的 propTypes，你需要引用他们并可以添加自己的propTypes，像这样:</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span>reduxForm<span class="token punctuation">,</span> propTypes<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">SimpleForm</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token keyword">static</span> propTypes <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token operator">...</span>propTypes<span class="token punctuation">,</span>
    <span class="token comment">// other props you might be using</span>
  <span class="token punctuation">}</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><h5 id="常用属性"><a href="#常用属性" class="header-anchor">#</a> 常用属性</h5> <ul><li><code>pristine</code> : <code>true</code> 表示表单数据为原始数据没被修改过，反之为 <code>dirty</code>。</li> <li><code>submitting</code> : 用于表示您的表单提交状态，他只会在您的表单提交后返回一个 <code>promise</code> 对象时起作用。 <code>false</code> 表示 <code>promise</code> 对象为 <code>resolved</code> 或 <code>rejected</code> 状态。</li> <li><code>handleSubmit(eventOrSubmit) : Function</code> : 提交表单的函数，如果表单需要验证，验证方法会被执行(包括同步和异步)。调用方法有两种:
<ul><li>组件内部直接调用 <code>&lt;form onSubmit={handleSubmit}&gt;</code></li> <li>赋值给prop外部调用 <code>&lt;MyDecoratedForm onSubmit={data =&gt; {//do something with data.}}/&gt;</code></li></ul></li></ul> <h3 id="field"><a href="#field" class="header-anchor">#</a> Field</h3> <p>所有您需要与 <code>store</code> 数据连接的表单组件，都可以用 <code>&lt;Field/&gt;</code>。在正确使用它之前，有三条基本概念您需要了解清楚:</p> <ol><li>必须包含 <code>name</code> 属性。可以是简单的字符串，如 <code>userName</code>、<code>password</code>，也可以是复杂的结构，如 <code>contact.billing.address[2].phones[1].areaCode</code>。</li> <li>必须包含 <code>component</code> 属性。可以是一个组件、无状态组件或者DOM所支持的默认的标签(input、textarea、select)。</li> <li>其他所有属性会通过prop传递到元素生成器中。如 <code>className</code></li></ol> <h5 id="importing-2"><a href="#importing-2" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> Field <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Field<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> Field <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法"><a href="#使用方法" class="header-anchor">#</a> 使用方法</h5> <p>1.组件</p> <p>可以是任何自定义的 <code>class</code> 组件活着其他第三方库。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token comment">// MyCustomInput.js</span>
<span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>

<span class="token keyword">class</span> <span class="token class-name">MyCustomInput</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> input<span class="token operator">:</span> <span class="token punctuation">{</span> value<span class="token punctuation">,</span> onChange <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token operator">&lt;</span>div<span class="token operator">&gt;</span>
        <span class="token operator">&lt;</span>span<span class="token operator">&gt;</span>The current value is <span class="token punctuation">{</span>value<span class="token punctuation">}</span><span class="token punctuation">.</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">&gt;</span>
        <span class="token operator">&lt;</span>button type<span class="token operator">=</span><span class="token string">&quot;button&quot;</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">onChange</span><span class="token punctuation">(</span>value <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>Inc<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">&gt;</span>
        <span class="token operator">&lt;</span>button type<span class="token operator">=</span><span class="token string">&quot;button&quot;</span> onClick<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">onChange</span><span class="token punctuation">(</span>value <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">&gt;</span>Dec<span class="token operator">&lt;</span><span class="token operator">/</span>button<span class="token operator">&gt;</span>
      <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>然后这样使用:</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> MyCustomInput <span class="token keyword">from</span> <span class="token string">'./MyCustomInput'</span>

<span class="token operator">...</span>

<span class="token operator">&lt;</span>Field name<span class="token operator">=</span><span class="token string">&quot;myField&quot;</span> component<span class="token operator">=</span><span class="token punctuation">{</span>MyCustomInput<span class="token punctuation">}</span><span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>2.无状态组件</p> <p>这是一个非常灵活的使用 <code>&lt;Field/&gt;</code> 的方法，使用方法和 <code>redux-form</code> 的前一个版本很相似。但必须在你的 <code>render()</code> 方法外定义它，否则它每次渲染都会被重建，并且由于组件的 <code>prop</code> 会变，就会强制 <code>&lt;Field/&gt;</code> 进行渲染。如果你在 <code>render()</code> 内部定义无状态组件，不但会拖慢你的app，而且组件的input每次都会在组件重新渲染的时候失去焦点。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token comment">// outside your render() method</span>
<span class="token keyword">const</span> <span class="token function-variable function">renderField</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">field</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
    <span class="token operator">&lt;</span>div className<span class="token operator">=</span><span class="token string">&quot;input-row&quot;</span><span class="token operator">&gt;</span>
      <span class="token operator">&lt;</span>input <span class="token punctuation">{</span><span class="token operator">...</span>field<span class="token punctuation">.</span>input<span class="token punctuation">}</span> type<span class="token operator">=</span><span class="token string">&quot;text&quot;</span><span class="token operator">/</span><span class="token operator">&gt;</span>
      <span class="token punctuation">{</span>field<span class="token punctuation">.</span>meta<span class="token punctuation">.</span>touched <span class="token operator">&amp;&amp;</span> field<span class="token punctuation">.</span>meta<span class="token punctuation">.</span>error <span class="token operator">&amp;&amp;</span>
       <span class="token operator">&lt;</span>span className<span class="token operator">=</span><span class="token string">&quot;error&quot;</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>field<span class="token punctuation">.</span>meta<span class="token punctuation">.</span>error<span class="token punctuation">}</span><span class="token operator">&lt;</span><span class="token operator">/</span>span<span class="token operator">&gt;</span><span class="token punctuation">}</span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">&gt;</span>
  <span class="token punctuation">)</span>

<span class="token comment">// inside your render() method</span>
<span class="token operator">&lt;</span>Field name<span class="token operator">=</span><span class="token string">&quot;myField&quot;</span> component<span class="token operator">=</span><span class="token punctuation">{</span>renderField<span class="token punctuation">}</span><span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><p>3.string: input, select, or textarea</p> <p>比如创建一个文字输入框组件</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token operator">&lt;</span>Field component<span class="token operator">=</span><span class="token string">&quot;input&quot;</span> type<span class="token operator">=</span><span class="token string">&quot;text&quot;</span><span class="token operator">/</span><span class="token operator">&gt;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h3 id="fields"><a href="#fields" class="header-anchor">#</a> Fields</h3> <p>与 <code>Field</code> 相似，但是它同时使用多个fields。<code>&lt;Fields/&gt;</code> 在 <code>name</code> 属性中使用一组表单name的数组，而不是用单一一个 <code>name</code> 属性来表示。</p> <p><strong>重要: 请节制使用 <code>&lt;Fields/&gt;</code>，其内部任何表单组件数据变化时，都会重新渲染整个 <code>&lt;Fields/&gt;</code>。因此会成为您app的性能瓶颈。除非你真的需要这么做，最好还是用 <code>&lt;Field/&gt;</code> 来一个个自定义您的表单组件</strong></p> <h5 id="importing-3"><a href="#importing-3" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> Fields <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Fields<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> Fields <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法-2"><a href="#使用方法-2" class="header-anchor">#</a> 使用方法</h5> <p>与 <code>&lt;Field/&gt;</code> 差不多，有2种使用方式，组件与无状态组件，这里不详细介绍。</p> <h3 id="fieldarray"><a href="#fieldarray" class="header-anchor">#</a> FieldArray</h3> <p>这个组件可以让你定义一系列的表单，它的工作原理和 <code>&lt;Field/&gt;</code> 一样。通过 <code>&lt;Field/&gt;</code>，给它一个 <code>name</code>，就可以映射到 <code>Redux state</code>中的指定位置。组件也可以通过连接到 <code>Redux state</code> 的 <code>props</code> 进行渲染。</p> <p>通过 <code>&lt;FieldArray/&gt;</code> ，你也需要和 <code>&lt;Field/&gt;</code> 一样给它一个 <code>name</code>。而你注入 <code>&lt;FieldArray/&gt;</code> 的组件会通过字段数组收到一系列的 <code>props</code>,用以查询、更新和迭代。</p> <h5 id="importing-4"><a href="#importing-4" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> FieldArray <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>FieldArray<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> FieldArray <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法-3"><a href="#使用方法-3" class="header-anchor">#</a> 使用方法</h5> <p>后面Demo里会具体介绍</p> <h3 id="form"><a href="#form" class="header-anchor">#</a> Form</h3> <p><code>Form</code> 组件对React的form组件进行了简单的封装，用以触发用 <code>redux-form</code> 修饰的组件的 <code>onSubmit</code> 函数。</p> <p>您可以在以下场景中使用它:</p> <ul><li>在您表单组件内部，可以通过 <code>onSubmit={this.props.handleSubmit(this.mySubmitFunction)}</code> 执行您的提交。</li> <li>或者
<ul><li>通过 <a href="http://redux-form.com/6.8.0/docs/api/ReduxForm.md/#-submit-promise-" target="_blank" rel="noopener noreferrer">submit() Instance API<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>来启动您的提交内容。(即，在引用您的表单组件的地方直接调用)</li> <li>通过 <code>dispatch</code> 一个 <code>action</code> 的方式启动调用。请参考 <a href="http://redux-form.com/6.8.0/examples/remoteSubmit/" target="_blank" rel="noopener noreferrer">Remote Submit Example<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></li></ul> <p>如果您只是将 <code>onSubmit</code> 函数作为你的配置或属性，那么你不需要用到这个组件。</p> <h5 id="importing-5"><a href="#importing-5" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> Form <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Form<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> Form <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法-4"><a href="#使用方法-4" class="header-anchor">#</a> 使用方法</h5> <p>只需要将您组件中所有 <code>&lt;form&gt;</code> 替换成 <code>&lt;Form&gt;</code> 即可。</p> <h3 id="formsection"><a href="#formsection" class="header-anchor">#</a> FormSection</h3> <p><code>FormSection</code> 可以很简单地将现有的表单组件分割成更小的组件，用以在复杂的表单中进行复用。它是通过明确规定好的 <code>Field</code>、<code>Fields</code>和<code>FieldArray</code>字组件 <code>name</code>的前缀来完成此功能的。</p> <h5 id="使用方法-5"><a href="#使用方法-5" class="header-anchor">#</a> 使用方法</h5> <p>这个例子所描述的业务是一个购买人与收件人视角的订单用户信息表单结构。购买人与收件人拥有相同的字段结构，因此把这个部分拆分成一个名为 <code>Party</code> 的组件是有意义的。假设现在 <code>Party</code> 包含 <code>givenName</code> <code>middleName</code> <code>surname</code> <code>address</code> 这几个字段，然后将 <code>address</code> 部分再度拆分成可重用的组件 <code>Address</code>。代码如下:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token comment">//Address.js</span>
<span class="token keyword">class</span> <span class="token class-name">Address</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>streetName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>number<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>zipCode<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">//Party.js</span>
<span class="token keyword">class</span> <span class="token class-name">Party</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>givenName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>middleName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>surname<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">FormSection</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>address<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
                </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Address</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">FormSection</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">//OrderForm.js</span>
<span class="token keyword">class</span> <span class="token class-name">OrderForm</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">onsubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token operator">...</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">FormSection</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>buyer<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
                </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Party</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">FormSection</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">FormSection</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>recipient<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
                </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Party</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">FormSection</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//don't forget to connect OrderForm with reduxForm()</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br></div></div><p>字段完整的名字最后将变成如 <code>buyer.address.streetName</code> 的形式，结果结构如下:</p> <div class="language-json line-numbers-mode"><pre class="language-json"><code><span class="token punctuation">{</span>
    <span class="token property">&quot;buyer&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">&quot;givenName&quot;</span><span class="token operator">:</span> <span class="token string">&quot;xxx&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;middleName&quot;</span><span class="token operator">:</span> <span class="token string">&quot;yyy&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;surname&quot;</span><span class="token operator">:</span> <span class="token string">&quot;zzz&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;address&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token property">&quot;streetName&quot;</span><span class="token operator">:</span> undefined<span class="token punctuation">,</span>
            <span class="token property">&quot;number&quot;</span><span class="token operator">:</span> <span class="token string">&quot;123&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;zipCode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;9090&quot;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token property">&quot;recipient&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
        <span class="token property">&quot;givenName&quot;</span><span class="token operator">:</span> <span class="token string">&quot;aaa&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;middleName&quot;</span><span class="token operator">:</span> <span class="token string">&quot;bbb&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;surname&quot;</span><span class="token operator">:</span> <span class="token string">&quot;ccc&quot;</span><span class="token punctuation">,</span>
        <span class="token property">&quot;address&quot;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token property">&quot;streetName&quot;</span><span class="token operator">:</span> <span class="token string">&quot;foo&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;number&quot;</span><span class="token operator">:</span> <span class="token string">&quot;4123&quot;</span><span class="token punctuation">,</span>
            <span class="token property">&quot;zipCode&quot;</span><span class="token operator">:</span> <span class="token string">&quot;78320&quot;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br></div></div><p>类似 <code>Address</code> 的组件很少更改它的 <code>name</code>，为了使组件继承 <code>FormSection</code> 而不是 <code>Component</code>，需要设置一个默认的 <code>name</code> 如下:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">class</span> <span class="token class-name">Address</span> <span class="token keyword">extends</span> <span class="token class-name">FormSection</span> <span class="token punctuation">{</span>
    <span class="token comment">//ES2015 syntax with babel transform-class-properties</span>
    <span class="token keyword">static</span> defaultProps <span class="token operator">=</span> <span class="token punctuation">{</span>
        name<span class="token operator">:</span> <span class="token string">&quot;address&quot;</span>
    <span class="token punctuation">}</span>
    <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>streetName<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>number<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
            </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Field</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>zipCode<span class="token punctuation">&quot;</span></span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>text<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">//Regular syntax:</span>
<span class="token comment">/*
Address.defaultProps = {
    name: &quot;address&quot;
}
*/</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br></div></div><h3 id="formvalues"><a href="#formvalues" class="header-anchor">#</a> formValues()</h3> <p>作为一个修饰，可以读取当前表单的 <code>value</code>。当表单子组件的 <code>onChange</code> 依赖于当前表单里的值，很有用。</p> <h5 id="importing-6"><a href="#importing-6" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> formValues <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>formValues<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> formValues <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法-6"><a href="#使用方法-6" class="header-anchor">#</a> 使用方法</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">const</span> ItemList <span class="token operator">=</span> <span class="token function">formValues</span><span class="token punctuation">(</span><span class="token string">'withVat'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>MyItemizedList<span class="token punctuation">)</span>

<span class="token keyword">const</span> ItemList <span class="token operator">=</span> <span class="token function">formValues</span><span class="token punctuation">(</span><span class="token punctuation">{</span>showVat<span class="token operator">:</span> <span class="token string">'withVat'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>MyItemizedList<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>这些装饰组件现在分别拥有了 <code>withVat</code>与<code>showVat</code>的 <code>props</code>。</p> <h3 id="formvalueselector"><a href="#formvalueselector" class="header-anchor">#</a> formValueSelector()</h3> <p><code>formValueSelector</code> 的API可以很方便的 <code>connect()</code> <code>state</code>的值到表单的 <code>value</code> 里。它可以通过表单的 <code>name</code> 为你的表单创建一个 <code>value</code> 拾取器。</p> <h5 id="importing-7"><a href="#importing-7" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> formValueSelector <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>formValueSelector<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> formValueSelector <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法-7"><a href="#使用方法-7" class="header-anchor">#</a> 使用方法</h5> <p>首先需要按照你表单的 <code>name</code> 创建一个 <code>selector</code>。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">const</span> selector <span class="token operator">=</span> <span class="token function">formValueSelector</span><span class="token punctuation">(</span><span class="token string">'myFormName'</span><span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>然后有几种方法使用 <code>selector</code>:</p> <p>1.拾取个别的字段</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token function">connect</span><span class="token punctuation">(</span>
  <span class="token parameter">state</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
    firstValue<span class="token operator">:</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'first'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    secondValue<span class="token operator">:</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'second'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">(</span>MyFormComponent<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>2.在分好组的 <code>prop</code> 中按组的方式拾取多个字段</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token function">connect</span><span class="token punctuation">(</span>
  <span class="token parameter">state</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
    myValues<span class="token operator">:</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'first'</span><span class="token punctuation">,</span> <span class="token string">'second'</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">(</span>MyFormComponent<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>3.把 <code>selector</code> 当作 <code>mapStateToProps</code> 来使用</p> <p>如果你不需要 <code>state</code> 中其他的属性值，<code>selector</code>作为<code>mapStateToProps</code>可以自动完成这个工作。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token function">connect</span><span class="token punctuation">(</span>
  <span class="token parameter">state</span> <span class="token operator">=&gt;</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'first'</span><span class="token punctuation">,</span> <span class="token string">'second'</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">(</span>MyFormComponent<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h3 id="reducer"><a href="#reducer" class="header-anchor">#</a> reducer</h3> <p>表单的<code>reducer</code>用来安装您的 <code>Redux state</code> 到您的表单中。</p> <p>如果您使用 <code>Immutablejs</code> 来管理您的 <code>Redux state</code>，你必须这么从 <code>redux-form/immutable</code> 中导入 <code>reducer</code> 模块。</p> <h5 id="es5例子"><a href="#es5例子" class="header-anchor">#</a> ES5例子</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> redux <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> formReducer <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>reducer<span class="token punctuation">;</span>
<span class="token comment">// Or with Immutablejs:</span>
<span class="token comment">// var formReducer = require('redux-form/immutable').reducer;</span>

<span class="token keyword">var</span> reducers <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// ... your other reducers here ...</span>
  form<span class="token operator">:</span> formReducer
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> reducer <span class="token operator">=</span> redux<span class="token punctuation">.</span><span class="token function">combineReducers</span><span class="token punctuation">(</span>reducers<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> store <span class="token operator">=</span> redux<span class="token punctuation">.</span><span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h5 id="es6例子"><a href="#es6例子" class="header-anchor">#</a> ES6例子</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore<span class="token punctuation">,</span> combineReducers <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> reducer <span class="token keyword">as</span> formReducer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>
<span class="token comment">// Or with Immutablejs:</span>
<span class="token comment">// import { reducer as formReducer } from 'redux-form/immutable';</span>

<span class="token keyword">const</span> reducers <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// ... your other reducers here ...</span>
  form<span class="token operator">:</span> formReducer
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> reducer <span class="token operator">=</span> <span class="token function">combineReducers</span><span class="token punctuation">(</span>reducers<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h3 id="reducer-plugin"><a href="#reducer-plugin" class="header-anchor">#</a> reducer.plugin</h3> <p>表单中返回一个通过附加指定功能 <code>reducers</code> 用以接受 <code>action</code> 的<code>reducer</code>。 它的参数应该是一个能映射 <code>formName</code>和一个<code>(state, action) =&gt; nextState</code> <code>reducer</code> 关系的一个对象。通过每一个 <code>reducer</code>的state只能是属于那个表单的一个片段。</p> <h5 id="说明"><a href="#说明" class="header-anchor">#</a> 说明</h5> <p><code>flux</code> 体系中最美的一部分应该是所有 <code>reducers</code>(或者 <code>Flux</code>中的标准术语 <code>stores</code>)可以接受所有 <code>actions</code>，他们可以修改基于这些 <code>action</code>来修改数据。举个例子，你有一个登录的表单，当你提交失败的时候，你想清楚密码输入框内的数据，哪怕你的登录的提交信息是属于另一个 <code>reducer/actions</code>体系，你的表单依然可以做出自己的响应。</p> <p>而不是使用 <code>redux-form</code> 中一个普通的 <code>reducer</code>，你可以通过调用 <code>plugin()</code> 函数来加强你的 <code>reducer</code>。</p> <p><em><strong>注:这是一个加强功能的操作用来修改你内部的 <code>redux-form</code> <code>state</code>的片段，如果你不小心使用，会把事情搞砸。</strong></em></p> <h5 id="例子"><a href="#例子" class="header-anchor">#</a> 例子</h5> <p>下面这个例子的作用是，当 <code>AUTH_LOGIN_FAIL</code> 的 <code>action</code> 被分发时，可以清除登录表单里的密码输入框:</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> createStore<span class="token punctuation">,</span> combineReducers <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> reducer <span class="token keyword">as</span> formReducer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">AUTH_LOGIN_FAIL</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'../actions/actionTypes'</span>

<span class="token keyword">const</span> reducers <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// ... your other reducers here ...</span>
  form<span class="token operator">:</span> formReducer<span class="token punctuation">.</span><span class="token function">plugin</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
    <span class="token function-variable function">login</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> action</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>   <span class="token comment">// &lt;----- 'login' is name of form given to reduxForm()</span>
      <span class="token keyword">switch</span><span class="token punctuation">(</span>action<span class="token punctuation">.</span>type<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">case</span> <span class="token constant">AUTH_LOGIN_FAIL</span><span class="token operator">:</span>
          <span class="token keyword">return</span> <span class="token punctuation">{</span>
            <span class="token operator">...</span>state<span class="token punctuation">,</span>
            values<span class="token operator">:</span> <span class="token punctuation">{</span>
              <span class="token operator">...</span>state<span class="token punctuation">.</span>values<span class="token punctuation">,</span>
              password<span class="token operator">:</span> <span class="token keyword">undefined</span> <span class="token comment">// &lt;----- clear password value</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
            fields<span class="token operator">:</span> <span class="token punctuation">{</span>
              <span class="token operator">...</span>state<span class="token punctuation">.</span>fields<span class="token punctuation">,</span>
              password<span class="token operator">:</span> <span class="token keyword">undefined</span> <span class="token comment">// &lt;----- clear field state, too (touched, etc.)</span>
            <span class="token punctuation">}</span>
          <span class="token punctuation">}</span>
        <span class="token keyword">default</span><span class="token operator">:</span>
          <span class="token keyword">return</span> state
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> reducer <span class="token operator">=</span> <span class="token function">combineReducers</span><span class="token punctuation">(</span>reducers<span class="token punctuation">)</span>
<span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token function">createStore</span><span class="token punctuation">(</span>reducer<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br></div></div><h3 id="submissionerror"><a href="#submissionerror" class="header-anchor">#</a> SubmissionError</h3> <p>这个 <code>throwable error</code> 用于从 <code>onSubmit</code> 返回一个表单验证错误信息。目的是用来区分 <code>promise</code> 失败的原因究竟是验证错误、AJAX I/O错误还是其他服务器错误。如果它是由于表单里 <code>{ field1: 'error', field2: 'error' }</code>产生的错误，那这个错误将会被添加到每一个标记过错误属性的字段里，就像异步表单验证错误一样。如果有一个错误没有指定的字段，但是应用到了整个表单，你需要继续传递它，就好像是某个字段调用的 <code>_error</code>一样，然后他会给出一个错误的属性。(就是不管他往外抛)</p> <h5 id="importing-8"><a href="#importing-8" class="header-anchor">#</a> Importing</h5> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">var</span> SubmissionError <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'redux-form'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>SubmissionError<span class="token punctuation">;</span>  <span class="token comment">// ES5</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> SubmissionError <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span><span class="token punctuation">;</span>  <span class="token comment">// ES6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h5 id="使用方法-8"><a href="#使用方法-8" class="header-anchor">#</a> 使用方法</h5> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">MyForm</span></span> <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token parameter">values</span> <span class="token operator">=&gt;</span>
  ajax<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>values<span class="token punctuation">)</span> <span class="token comment">// however you send data to your server...</span>
    <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">error</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      <span class="token comment">// how you pass server-side validation errors back is up to you</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>validationErrors<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">SubmissionError</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span>validationErrors<span class="token punctuation">)</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">// what you do about other communication errors is up to you</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></span><span class="token punctuation">/&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h3 id="action-creators"><a href="#action-creators" class="header-anchor">#</a> Action Creators</h3> <p><code>redux-form</code> 对外开放了所有的内部 <code>action creators</code>，允许你按找你的意愿来完成对分发 <code>action</code> 的控制。进而，官方推荐您在完成您大部分需求的时候，对于那些表单里指定需求的字段的 <code>action</code>来说，当作这些 <code>action</code> 已经绑定到 <code>dispatch</code>一样，直接将这些 <code>action</code> 通过 <code>props</code> 传递。</p> <p>具体 <code>action</code> 请参考官方文档。</p> <h3 id="selectors"><a href="#selectors" class="header-anchor">#</a> Selectors</h3> <p><code>redux-form</code> 提供了一系列有用的 <code>Redux state</code> 拾取器，可以在app的任何地方任何表单内拾取 <code>state</code> 上的数据。</p> <p>下列所有拾取器拥有统一的使用方法: 他们都(除了<code>getFormNames</code>)使用表单的名字，来创建一个拾取器，无论表单的 <code>state</code>是什么。</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">import</span> <span class="token punctuation">{</span>
  getFormValues<span class="token punctuation">,</span>
  getFormInitialValues<span class="token punctuation">,</span>
  getFormSyncErrors<span class="token punctuation">,</span>
  getFormMeta<span class="token punctuation">,</span>
  getFormAsyncErrors<span class="token punctuation">,</span>
  getFormSyncWarnings<span class="token punctuation">,</span>
  getFormSubmitErrors<span class="token punctuation">,</span>
  getFormNames<span class="token punctuation">,</span>
  isDirty<span class="token punctuation">,</span>
  isPristine<span class="token punctuation">,</span>
  isValid<span class="token punctuation">,</span>
  isInvalid<span class="token punctuation">,</span>
  isSubmitting<span class="token punctuation">,</span>
  hasSubmitSucceeded<span class="token punctuation">,</span>
  hasSubmitFailed
<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span>

MyComponent <span class="token operator">=</span> <span class="token function">connect</span><span class="token punctuation">(</span>
  <span class="token parameter">state</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
    values<span class="token operator">:</span> <span class="token function">getFormValues</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    initialValues<span class="token operator">:</span> <span class="token function">getFormInitialValues</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    syncErrors<span class="token operator">:</span> <span class="token function">getFormSyncErrors</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    fields<span class="token operator">:</span> <span class="token function">getFormMeta</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    asyncErrors<span class="token operator">:</span> <span class="token function">getFormAsyncErrors</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    syncWarnings<span class="token operator">:</span> <span class="token function">getFormSyncWarnings</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    submitErrors<span class="token operator">:</span> <span class="token function">getFormSubmitErrors</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    names<span class="token operator">:</span> <span class="token function">getFormNames</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    dirty<span class="token operator">:</span> <span class="token function">isDirty</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    pristine<span class="token operator">:</span> <span class="token function">isPristine</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    valid<span class="token operator">:</span> <span class="token function">isValid</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    invalid<span class="token operator">:</span> <span class="token function">isInvalid</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    submitting<span class="token operator">:</span> <span class="token function">isSubmitting</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    submitSucceeded<span class="token operator">:</span> <span class="token function">hasSubmitSucceeded</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span><span class="token punctuation">,</span>
    submitFailed<span class="token operator">:</span> <span class="token function">hasSubmitFailed</span><span class="token punctuation">(</span><span class="token string">'myForm'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>state<span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">(</span>MyComponent<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br></div></div><h2 id="examples"><a href="#examples" class="header-anchor">#</a> Examples</h2> <h3 id="simple-form"><a href="#simple-form" class="header-anchor">#</a> Simple Form</h3> <p>这个例子把表单所有基本的元素都列了出来，和官方Demo有所区别的是，增加了2个 <code>type</code> 为 <code>file</code> 的 <code>Field</code> (直接在 <code>Field</code> 中使用 <code>file</code> 的类型会有点问题)，一个是使用了jQuery的 <a href="https://github.com/JeremyFagis/dropify" target="_blank" rel="noopener noreferrer">dropify<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 编写的上传单个文件的组件 <code>MyDropify</code>，一个是使用了 <code>dropzone</code> 编写的上传多个文件的组件 <code>MyDropzone</code> (在这里使用了 <a href="https://github.com/okonet/react-dropzone" target="_blank" rel="noopener noreferrer">react-dropzone<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 和 <code>redux-form</code> 的组合)。官方的例子不单独介绍了，主要贴一下两个自定义 <code>Field</code>。</p> <p><em><strong>注：由于reducer设计之初是纯函数，而提交文件的表单最后取得的值是一个 <code>file</code> 对象，当您使用了 <a href="https://github.com/leoasis/redux-immutable-state-invariant" target="_blank" rel="noopener noreferrer">redux-immutable-state-invariant<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 之类的检测工具，对其中诸如 <code>lastModifiedDate</code> 的值会报错，<a href="http://redux.js.org/docs/Troubleshooting.html#never-mutate-reducer-arguments" target="_blank" rel="noopener noreferrer">具体请看<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>。在此，我们暂时先不考虑immutable的问题。</strong></em></p> <h5 id="simple路径"><a href="#simple路径" class="header-anchor">#</a> Simple路径</h5> <p><code>src/components/demo/simple/</code></p> <h5 id="mydropify"><a href="#mydropify" class="header-anchor">#</a> MyDropify</h5> <p><code>src/components/utils/MyDropify.js</code></p> <p>代码:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> $ <span class="token operator">=</span> window<span class="token punctuation">.</span>$<span class="token punctuation">;</span>
<span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'dropify'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">MyDropify</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'.dropify'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">dropify</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> input<span class="token punctuation">,</span>dataAllowedFileExtensions <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props
    <span class="token keyword">const</span> <span class="token function-variable function">onAttachmentChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        e<span class="token punctuation">.</span><span class="token function">preventDefault</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">const</span> files <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>files<span class="token punctuation">]</span><span class="token punctuation">;</span>
        input<span class="token punctuation">.</span><span class="token function">onChange</span><span class="token punctuation">(</span>files<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>file<span class="token punctuation">&quot;</span></span>
               <span class="token attr-name">onChange</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onAttachmentChange<span class="token punctuation">}</span></span>
               <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>dropify<span class="token punctuation">&quot;</span></span>
               <span class="token attr-name">data-allowed-file-extensions</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>dataAllowedFileExtensions<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> MyDropify<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br></div></div><p>使用方法:</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code>  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>form-group<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input-group<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token punctuation">&gt;</span></span>Dropify<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Field</span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span>{MyDropify}</span>
             <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>inputfile1<span class="token punctuation">&quot;</span></span>
             <span class="token attr-name">dataAllowedFileExtensions</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>doc docx txt pdf xls xlsx jpg png bmp<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Field</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p><a href="https://github.com/JeremyFagis/dropify" target="_blank" rel="noopener noreferrer">dropify<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 的具体用法请参考其官方文档。</p> <h5 id="mydropzone"><a href="#mydropzone" class="header-anchor">#</a> MyDropzone</h5> <p><code>src/components/utils/MyDropify.js</code></p> <p>代码:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> Dropzone <span class="token keyword">from</span> <span class="token string">'react-dropzone'</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">MyDropzone</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> input<span class="token punctuation">,</span>desc<span class="token punctuation">,</span>accept <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props
    <span class="token keyword">const</span> <span class="token function-variable function">onDrop</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">files</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
        input<span class="token punctuation">.</span><span class="token function">onChange</span><span class="token punctuation">(</span>files<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Dropzone</span></span> <span class="token attr-name">onDrop</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onDrop<span class="token punctuation">}</span></span> <span class="token attr-name">accept</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>accept<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> isDragActive<span class="token punctuation">,</span> isDragReject<span class="token punctuation">,</span> acceptedFiles<span class="token punctuation">,</span> rejectedFiles <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
           <span class="token keyword">if</span> <span class="token punctuation">(</span>isDragActive<span class="token punctuation">)</span> <span class="token punctuation">{</span>
             <span class="token keyword">return</span> <span class="token string">&quot;This file is authorized&quot;</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span>
           <span class="token keyword">if</span> <span class="token punctuation">(</span>isDragReject<span class="token punctuation">)</span> <span class="token punctuation">{</span>
             <span class="token keyword">return</span> <span class="token string">&quot;This file is not authorized&quot;</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span>
           <span class="token keyword">return</span> acceptedFiles<span class="token punctuation">.</span>length <span class="token operator">||</span> rejectedFiles<span class="token punctuation">.</span>length
             <span class="token operator">?</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Accepted </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>acceptedFiles<span class="token punctuation">.</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">, rejected </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>rejectedFiles<span class="token punctuation">.</span>length<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> files</span><span class="token template-punctuation string">`</span></span>
            <span class="token operator">:</span> desc<span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Dropzone</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> MyDropzone<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br></div></div><p>使用方法:</p> <div class="language-html line-numbers-mode"><pre class="language-html"><code>  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>form-group<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input-group<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token punctuation">&gt;</span></span>Dropzone<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Field</span> <span class="token attr-name">component</span><span class="token attr-value"><span class="token punctuation">=</span>{MyDropzone}</span>
             <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>inputfile2<span class="token punctuation">&quot;</span></span>
             <span class="token attr-name">desc</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>My Dropzone<span class="token punctuation">&quot;</span></span>
             <span class="token attr-name">accept</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>image/png,image/jpeg<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>Field</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p><code>react-dropzone</code> 和jQuery版本的有所区别，使用过 <code>dropzone</code> 的应该都知道选择文件可以渲染到框体内，react版本的 <code>dropzone</code> 原声不带这个功能，但它提供了详尽的方法可以自己实现很多功能，比如选择完文件可以渲染到组件中，有时间我再完善此功能。</p> <h3 id="sync-validation"><a href="#sync-validation" class="header-anchor">#</a> Sync Validation</h3> <p>同步的表单验证，包括了错误和警告型配置。官方Demo中只演示了输入框的验证，而这里准备了包括 <code>radio</code> <code>select</code> <code>textarea</code> 的验证方式(<code>checkbox</code> 我会在单独的一章讲解)，调用方法可以参见本文的源代码。</p> <h5 id="sync-validation路径"><a href="#sync-validation路径" class="header-anchor">#</a> Sync Validation路径</h5> <p><code>src/components/demo/syncValidation/</code></p> <h5 id="radiofield"><a href="#radiofield" class="header-anchor">#</a> radioField</h5> <p><code>src/components/utils/validation/radioField.js</code></p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">inputField</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>
  input<span class="token punctuation">,</span>
  label<span class="token punctuation">,</span>
  type<span class="token punctuation">,</span>
  meta<span class="token operator">:</span> <span class="token punctuation">{</span> touched<span class="token punctuation">,</span> error<span class="token punctuation">,</span> warning <span class="token punctuation">}</span>
<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>touched <span class="token operator">&amp;&amp;</span> error <span class="token operator">?</span> <span class="token string">'has-error form-group'</span><span class="token operator">:</span><span class="token string">'form-group'</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input-group<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input-group-addon<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>label<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">input</span><span class="token punctuation">}</span></span> <span class="token attr-name">placeholder</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>label<span class="token punctuation">}</span></span> <span class="token attr-name">type</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>type<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>form-control<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token punctuation">{</span>touched <span class="token operator">&amp;&amp;</span>
      <span class="token punctuation">(</span><span class="token punctuation">(</span>error <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>help-block with-errors<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>error<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span> <span class="token operator">||</span>
        <span class="token punctuation">(</span>warning <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>help-block with-errors<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>warning<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> inputField<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><h5 id="selectfield"><a href="#selectfield" class="header-anchor">#</a> selectField</h5> <p><code>src/components/utils/validation/selectField.js</code></p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token function-variable function">selectField</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>
  input<span class="token punctuation">,</span>
  label<span class="token punctuation">,</span>
  selects<span class="token punctuation">,</span>
  meta<span class="token operator">:</span> <span class="token punctuation">{</span> touched<span class="token punctuation">,</span> error<span class="token punctuation">,</span> warning <span class="token punctuation">}</span>
<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>touched <span class="token operator">&amp;&amp;</span> error <span class="token operator">?</span> <span class="token string">'has-error form-group'</span><span class="token operator">:</span><span class="token string">'form-group'</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input-group<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>span</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>input-group-addon<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>label<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>span</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>select</span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">input</span><span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>form-control<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>
          selects<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>option</span> <span class="token attr-name">key</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>i<span class="token punctuation">}</span></span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>value<span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>item<span class="token punctuation">.</span>text<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>option</span><span class="token punctuation">&gt;</span></span>
          <span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>select</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token punctuation">{</span>touched <span class="token operator">&amp;&amp;</span>
      <span class="token punctuation">(</span><span class="token punctuation">(</span>error <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>help-block with-errors<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>error<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span> <span class="token operator">||</span>
        <span class="token punctuation">(</span>warning <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>help-block with-errors<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>warning<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> selectField<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h5 id="textareafield"><a href="#textareafield" class="header-anchor">#</a> textareaField</h5> <p><code>src/components/utils/validation/textareaField.js</code></p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> <span class="token function-variable function">textareaField</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>
  input<span class="token punctuation">,</span>
  label<span class="token punctuation">,</span>
  type<span class="token punctuation">,</span>
  cols<span class="token punctuation">,</span>
  rows<span class="token punctuation">,</span>
  meta<span class="token operator">:</span> <span class="token punctuation">{</span> touched<span class="token punctuation">,</span> error<span class="token punctuation">,</span> warning <span class="token punctuation">}</span>
<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>touched <span class="token operator">&amp;&amp;</span> error <span class="token operator">?</span> <span class="token string">'has-error form-group'</span><span class="token operator">:</span><span class="token string">'form-group'</span><span class="token punctuation">}</span></span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>label<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>textarea</span> <span class="token spread"><span class="token punctuation">{</span><span class="token punctuation">...</span><span class="token attr-value">input</span><span class="token punctuation">}</span></span> <span class="token attr-name">cols</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>cols<span class="token punctuation">}</span></span> <span class="token attr-name">rows</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>rows<span class="token punctuation">}</span></span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>form-control<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>textarea</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
    </span><span class="token punctuation">{</span>touched <span class="token operator">&amp;&amp;</span>
      <span class="token punctuation">(</span><span class="token punctuation">(</span>error <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>help-block with-errors<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>error<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span> <span class="token operator">||</span>
        <span class="token punctuation">(</span>warning <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">className</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>help-block with-errors<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token punctuation">{</span>warning<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> textareaField<span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><h3 id="field-level-validation"><a href="#field-level-validation" class="header-anchor">#</a> Field-Level Validation</h3> <p>除了提供一个验证方法一起验证表单里的值这种方法之外，还可以对每一个 <code>&lt;Field/&gt;</code> 或 <code>&lt;FieldArray/&gt;</code> 分别做验证。官方给的Demo已经足够说明问题了，在这里只针对上面的 <code>Sync Validation</code> 作简单的改写。具体请看代码。</p> <h3 id="submit-validation"><a href="#submit-validation" class="header-anchor">#</a> Submit Validation</h3> <p>一种服务器表单验证较好的方法是在调用 <code>onSubnit</code> 之后返回一个 <code>rejected</code> 的 <code>promise</code> 对象。当您的表单被提交时，有2种方法提供给 <code>redux-form</code> 这个函数。</p> <ol><li>把他当作一个 <code>onSubmit</code> 的 <code>prop</code> 传递给您的装饰组件。那样的话，你可以在您的装饰组件中使用 <code>onSubmit={this.props.handleSubmit}</code> 确保当用户点击提交按钮的时候触发这个函数。</li> <li>把他当作一个参数传递给您装饰组件内的 <code>this.props.handleSubmit</code> 函数。这种情况下，你需要使用 <code>onClick={this.props.handleSubmit(mySubmit)}</code> 来确保当用户点击提交按钮的时候触发这个函数。</li></ol> <p>这个错误信息的显示方式和同步验证(Synchronous Validation)后的错误信息一样，但他是通过 <code>onSubmit</code> 函数返回一个封装过的 <code>SubmissionError</code> 对象。这个验证错误就像HTTP的400或500错误一样，和I/O错误是有区别的，并且他还会是这个提交的 <code>promise</code> 对象的状态置为 <code>rejected</code>。</p> <p>DEMO中没什么花头，和官方一样，就是基于 <code>SyncValidation</code> 把表单验证的逻辑放在了提交后的逻辑中，并抛出了一个 <code>SubmissionError</code>。</p> <h3 id="async-validation"><a href="#async-validation" class="header-anchor">#</a> Async Validation</h3> <p>服务器表单验证的方式比较推荐使用<a href="#SubmitValidation">Submit Validation</a>，但是可能存在当您填写表单的时候，同时需要服务器端来验证。有一个经典的例子是当一个用户选取一个值，比如用户名，它必须是您系统中唯一的一个值。</p> <p>为了写一个异步的表单验证，需要给 <code>redux-form</code> 提供一个异步验证的函数(asyncValidation)用来提供一个可以从表单获取数据的一个对象，然后 <code>Redux</code> 分发这个函数，返回一个状态为拥有一个错误对象的 <code>rejects</code>或状态为 <code>reslove</code> 的 <code>promise</code> 对象。</p> <p>您需要同时指定某几个字段，通过 <code>asyncBlurFields</code> 的属性配置，来标记是否需要在他们失去焦点的时候触发这个异步验证。</p> <h5 id="重要"><a href="#重要" class="header-anchor">#</a> 重要</h5> <ol><li>异步验证会在 <code>onSubmit</code> 之前被调用，所以如果你关心的是 <code>onSubmit</code> 验证，你需要使用 <a href="#SubmitValidation">Submit Validation</a></li> <li>当一个字段的同步验证错误时，那它的失去焦点的时候将不会触发异步验证。</li></ol> <p>Demo中的自定义 <code>&lt;Field/&gt;</code> 的 <code>meta</code> 中有一个 <code>asyncValidating</code>，来标识异步验证的 <code>promise</code> 对象的 <code>Pending</code> 状态。</p> <h3 id="initialize-from-state"><a href="#initialize-from-state" class="header-anchor">#</a> Initialize From State</h3> <p>通过 <code>initialValues</code> 属性或 <code>reduxForm()</code> 配置的参数所提供的数据，被加载到表单 <code>state</code> 中，并且把这些初始化数据作为原始数据(pristine)。当 <code>reset()</code> 触发的时候，也会返回这些值。除了保存这些 <code>pristine</code> 值，初始化您表单的这个操作也会替换表单里已经存在的值。</p> <p>在许多应用中，这些值可能是来自服务器并且储存在其他 <code>reducer</code> 中的。想要得到这些值，你需要使用 <code>connect()</code> 去自己链接 <code>state</code> 然后映射这些数据到您的 <code>initialValues</code> 属性里。</p> <p>默认情况下，你只需要通过 <code>initialValues</code> 初始化您的表单组件一次即可。目前有2种方法可以通过新的 <code>pristine</code> 值重新初始化表单。</p> <ol><li>传递一个 <code>enableReinitialize</code> 属性或配置 <code>reduxForm()</code> 中的参数为true就可以让表单在每次 <code>initialValues</code> 属性变化的时候重新初始化，生成一个新的 <code>pristine</code> 值。如果想要在重新初始化的时候保持已改变过的表单的值，可以设置 <code>keepDirtyOnReinitialize</code> 为true。默认情况下，重新初始化会将 <code>pristine</code> 值替换掉已改变过的表单的值。</li> <li>发出一个 <code>INITIALIZE</code> action(用 <code>redux-form</code> action生成器生成)。</li></ol> <p>此Demo较之官方Demo，增加了 <code>enableReinitialize</code> 和 <code>keepDirtyOnReinitialize</code> 的用法。以下是代码片段。</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code>InitializeFromStateForm <span class="token operator">=</span> <span class="token function">reduxForm</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  form<span class="token operator">:</span> <span class="token string">'initializeFromState'</span><span class="token punctuation">,</span><span class="token comment">// a unique identifier for this form</span>
  enableReinitialize<span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">,</span>
  keepDirtyOnReinitialize<span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">,</span><span class="token comment">// 这个值表示重新初始化表单后，不替换已更改的值，可以用clear来测试</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>InitializeFromStateForm<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h3 id="selecting-form-values"><a href="#selecting-form-values" class="header-anchor">#</a> Selecting Form Values</h3> <p>有时候您希望访问表单组件中某些字段的值，你需要在 <code>store</code> 中直接 <code>connect()</code> 表单的值。在一般的使用情况下，<code>redux-form</code> 通过 <code>formValueSelector</code> 提供了一个方便的选择器。</p> <p><strong>警告: 需要节制使用这个机制，因为这样的话，表单里的某一个值一旦发生改变，就会重新渲染您的组件。</strong></p> <p>代码片段:</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token comment">// Decorate with reduxForm(). It will read the initialValues prop provided by connect()</span>
SelectingFormValuesForm <span class="token operator">=</span> <span class="token function">reduxForm</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  form<span class="token operator">:</span> <span class="token string">'selectingFormValues'</span><span class="token punctuation">,</span><span class="token comment">// a unique identifier for this form</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>SelectingFormValuesForm<span class="token punctuation">)</span>

<span class="token comment">// Decorate with connect to read form values</span>
<span class="token keyword">const</span> selector <span class="token operator">=</span> <span class="token function">formValueSelector</span><span class="token punctuation">(</span><span class="token string">'selectingFormValues'</span><span class="token punctuation">)</span> <span class="token comment">// &lt;-- same as form name</span>
SelectingFormValuesForm <span class="token operator">=</span> <span class="token function">connect</span><span class="token punctuation">(</span><span class="token parameter">state</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// can select values individually</span>
  <span class="token keyword">const</span> hasEmailValue <span class="token operator">=</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'hasEmail'</span><span class="token punctuation">)</span>
  <span class="token keyword">const</span> favoriteColorValue <span class="token operator">=</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'favoriteColor'</span><span class="token punctuation">)</span>
  <span class="token comment">// or together as a group</span>
  <span class="token keyword">const</span> <span class="token punctuation">{</span> firstName<span class="token punctuation">,</span> lastName <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">selector</span><span class="token punctuation">(</span>state<span class="token punctuation">,</span> <span class="token string">'firstName'</span><span class="token punctuation">,</span> <span class="token string">'lastName'</span><span class="token punctuation">)</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    hasEmailValue<span class="token punctuation">,</span>
    favoriteColorValue<span class="token punctuation">,</span>
    fullName<span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>firstName <span class="token operator">||</span> <span class="token string">''</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>lastName <span class="token operator">||</span> <span class="token string">''</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span>SelectingFormValuesForm<span class="token punctuation">)</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> SelectingFormValuesForm
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br></div></div><h3 id="field-array"><a href="#field-array" class="header-anchor">#</a> Field Array</h3> <p>这个例子展示了怎样构建一个字段组，包括拥有一个字段的和拥有一组字段的字段组。在这个表单里，每一个俱乐部的成员都有姓和名，还有一个兴趣的列表。以下这些数组的操作 <code>insert, pop, push, remove, shift, swap, unshift</code> 行为是被允许的:(更多详细的内容可以参考<a href="#FieldArray">FieldArray Docs</a>)</p> <ul><li>一个 <code>action</code> 的原始构造</li> <li>通过您表单的 <code>this.props.array</code> 对象绑定的 <code>action</code></li> <li>同时绑定表单和通过 <code>FieldArray</code> 组件获得的对象上的数组的 <code>action</code></li></ul> <h3 id="remote-submit"><a href="#remote-submit" class="header-anchor">#</a> Remote Submit</h3> <p>这个例子演示了一个表单如何从一个无关的组件或中间件中发送的一个 <code>SUBMIT</code> 的action来执行提交逻辑。</p> <p>这个例子里你所看到的的提交按钮，不是直接与表单组件直接链接的，它的作用只是通过 <code>Redux</code> 发送的一个提交的 <code>action</code>。</p> <p>要注意它的工作方式，这个提交函数必须通过 <code>reduxForm()</code> 配置参数的传递或通过 <code>prop</code> 提供给表单组件。以下是发送这个action的方式:</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> connect <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-redux'</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> submit <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'redux-form'</span>

<span class="token keyword">const</span> style <span class="token operator">=</span> <span class="token punctuation">{</span>
  padding<span class="token operator">:</span> <span class="token string">'10px 20px'</span><span class="token punctuation">,</span>
  width<span class="token operator">:</span> <span class="token number">140</span><span class="token punctuation">,</span>
  display<span class="token operator">:</span> <span class="token string">'block'</span><span class="token punctuation">,</span>
  margin<span class="token operator">:</span> <span class="token string">'20px auto'</span><span class="token punctuation">,</span>
  fontSize<span class="token operator">:</span> <span class="token string">'16px'</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">RemoteSubmitButton</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> dispatch <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span>
    <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>button<span class="token punctuation">&quot;</span></span>
    <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>style<span class="token punctuation">}</span></span>
    <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">dispatch</span><span class="token punctuation">(</span><span class="token function">submit</span><span class="token punctuation">(</span><span class="token string">'remoteSubmit'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span>
  <span class="token punctuation">&gt;</span></span><span class="token plain-text">
    Submit
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
<span class="token punctuation">)</span>
<span class="token comment">//   remoteSubmit 为表单的名字</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token function">connect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span>RemoteSubmitButton<span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br></div></div><h3 id="field-normalizing"><a href="#field-normalizing" class="header-anchor">#</a> Field Normalizing</h3> <p>当您需要在用户输入和 <code>store</code> 中的数据之间施加某些控制，你可以使用 <code>normalizer</code>。<code>normalizer</code> 就是一个每当值改变是，可以在保存到 <code>store</code> 之前进行某些转换的一个函数。</p> <p>一个常用的例子：你需要一个某些经过格式化的值，比如电话号码或信用卡号。</p> <p><code>Normalizers</code> 传递了4个参数:</p> <ul><li><code>value</code> - 你设置了 <code>normalizer</code> 字段的值</li> <li><code>previousValue</code> - 这个值最近一次变化之前的一个值</li> <li><code>allValues</code> - 表单中，所有字段当前的值</li> <li><code>previousAllValues</code> - 表单中，所有字段在最近一次变化前的值</li></ul> <p>这些可以使你基于表单中另外一个字段而限制某个特定的字段。比如例子中的字段最小最大值：这里你不能设置 <code>min</code> 中的值比 <code>max</code> 中的值大，不能设置 <code>max</code> 中的值比 <code>min</code> 的值更小(下面有代码)</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">const</span> <span class="token function-variable function">upper</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=&gt;</span> value <span class="token operator">&amp;&amp;</span> value<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">lower</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=&gt;</span> value <span class="token operator">&amp;&amp;</span> value<span class="token punctuation">.</span><span class="token function">toLowerCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> <span class="token function-variable function">lessThan</span> <span class="token operator">=</span> <span class="token parameter">otherField</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> previousValue<span class="token punctuation">,</span> allValues</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
  <span class="token function">parseFloat</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">&lt;</span> <span class="token function">parseFloat</span><span class="token punctuation">(</span>allValues<span class="token punctuation">[</span>otherField<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">?</span> value <span class="token operator">:</span> previousValue
<span class="token keyword">const</span> <span class="token function-variable function">greaterThan</span> <span class="token operator">=</span> <span class="token parameter">otherField</span> <span class="token operator">=&gt;</span> <span class="token punctuation">(</span><span class="token parameter">value<span class="token punctuation">,</span> previousValue<span class="token punctuation">,</span> allValues</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span>
  <span class="token function">parseFloat</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token function">parseFloat</span><span class="token punctuation">(</span>allValues<span class="token punctuation">[</span>otherField<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">?</span> value <span class="token operator">:</span> previousValue
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><p>下面是对电话号码处理的逻辑</p> <div class="language-javascript line-numbers-mode"><pre class="language-javascript"><code><span class="token keyword">const</span> <span class="token function-variable function">normalizePhone</span> <span class="token operator">=</span> <span class="token parameter">value</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>value<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> value
  <span class="token punctuation">}</span>

  <span class="token keyword">const</span> onlyNums <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex">/[^\d]/g</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>onlyNums<span class="token punctuation">.</span>length <span class="token operator">&lt;=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> onlyNums
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>onlyNums<span class="token punctuation">.</span>length <span class="token operator">&lt;=</span> <span class="token number">7</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>onlyNums<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>onlyNums<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>onlyNums<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>onlyNums<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>onlyNums<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h3 id="wizard"><a href="#wizard" class="header-anchor">#</a> Wizard</h3> <p>一种常见的UI设计模式是把一个单一的表单分割成几组分开的表单形式，最为熟知的就是 <code>Wizard</code>。使用 <code>redux-form</code> 的话有好多方式可以来做这种设计，但最简单和最推荐的方式是遵循一下几种指示:</p> <ul><li>把每一个页面都用同一个表单名字连接到 <code>reduxForm()</code></li> <li>指定 <code>destroyOnUnmount</code>为 <code>false</code> 就可以在表单组件卸载的时候保存表单数据</li> <li>你可以为整个表单指定一个同步验证函数</li> <li>使用 <code>onSubmit</code> 来触发进入下一步，因为它强制运行验证函数</li></ul> <p>需要由你自己来实现的:</p> <ul><li>在提交成功之后手动调用 <code>props.destory()</code></li></ul> <p>例子里的代码主要列出控制 <code>Wizard</code> 的组件，其他组件的用法已被我们熟知。</p> <div class="language-jsx line-numbers-mode"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span>
<span class="token keyword">import</span> PropTypes <span class="token keyword">from</span> <span class="token string">'prop-types'</span>
<span class="token keyword">import</span> WizardFormFirstPage <span class="token keyword">from</span> <span class="token string">'./WizardFormFirstPage'</span>
<span class="token keyword">import</span> WizardFormSecondPage <span class="token keyword">from</span> <span class="token string">'./WizardFormSecondPage'</span>
<span class="token keyword">import</span> WizardFormThirdPage <span class="token keyword">from</span> <span class="token string">'./WizardFormThirdPage'</span>

<span class="token keyword">class</span> <span class="token class-name">WizardForm</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">super</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>nextPage <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">nextPage</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>previousPage <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">previousPage</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> <span class="token punctuation">{</span>
      page<span class="token operator">:</span> <span class="token number">1</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
  <span class="token function">nextPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> page<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>page <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">previousPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> page<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">.</span>page <span class="token operator">-</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span>

  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> onSubmit <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props
    <span class="token keyword">const</span> <span class="token punctuation">{</span> page <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state
    <span class="token keyword">return</span> <span class="token punctuation">(</span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span>page <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">&amp;&amp;</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">WizardFormFirstPage</span></span> <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>nextPage<span class="token punctuation">}</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token punctuation">{</span>page <span class="token operator">===</span> <span class="token number">2</span> <span class="token operator">&amp;&amp;</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">WizardFormSecondPage</span></span>
            <span class="token attr-name">previousPage</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>previousPage<span class="token punctuation">}</span></span>
            <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>nextPage<span class="token punctuation">}</span></span>
          <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token punctuation">{</span>page <span class="token operator">===</span> <span class="token number">3</span> <span class="token operator">&amp;&amp;</span>
          <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">WizardFormThirdPage</span></span>
            <span class="token attr-name">previousPage</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token keyword">this</span><span class="token punctuation">.</span>previousPage<span class="token punctuation">}</span></span>
            <span class="token attr-name">onSubmit</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onSubmit<span class="token punctuation">}</span></span>
          <span class="token punctuation">/&gt;</span></span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

WizardForm<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span>
  onSubmit<span class="token operator">:</span> PropTypes<span class="token punctuation">.</span>func<span class="token punctuation">.</span>isRequired
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> WizardForm
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br></div></div></div> <footer class="page-edit"><!----> <!----></footer> <!----> <!----></article> </main></div> <footer data-v-c305a0ca>Copyright © 2020 Ted Yuen</footer></div><div class="global-ui"><!----></div></div>
    <script src="/assets/js/app.a5c0d474.js" defer></script><script src="/assets/js/15.57df9f8e.js" defer></script><script src="/assets/js/17.06d3e00b.js" defer></script>
  </body>
</html>
